﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

using WeatherClockWidget.Domain;

using E = HTCHome.Core.Environment;
using System.IO;
using HTCHome.Core;
using System.Threading;
using Environment = System.Environment;
using Path = System.IO.Path;

namespace WeatherClockWidget
{
    /// <summary>
    /// Interaction logic for WeatherClock.xaml
    /// </summary>
    public partial class WeatherClock : UserControl
    {
        private DispatcherTimer timer;
        private DispatcherTimer weatherTimer;

        public List<WeatherProvider> providers;
        public WeatherProvider currentProvider;
        public WeatherReport weatherReport;

        private Options options;

        private MenuItem lastCitiesItem;
        private string hoursFormat = "HH";

        private int lastHour;

        private List<string> pictures = new List<string>();
        private Random r = new Random(System.Environment.TickCount);
        private int count; //used for switching pictures

        public WeatherClock()
        {
            InitializeComponent();
        }

        public void Load()
        {
            weatherReport = WeatherReport.Read(E.Path + "\\WeatherClock\\Weather.data");

            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += new EventHandler(timer_Tick);

            weatherTimer = new DispatcherTimer();
            weatherTimer.Interval = TimeSpan.FromMinutes(Properties.Settings.Default.Interval);
            weatherTimer.Tick += weatherTimer_Tick;

            Month.Text = DateTime.Today.ToString("MMMM");
            Day.Text = DateTime.Today.Day.ToString();

            Hours.Text = DateTime.Now.AddHours(-1).Hour.ToString();
            Minutes.Text = DateTime.Now.AddMinutes(-2).Minute.ToString();

            Location.Text = weatherReport.Location;
            NowSky.Text = weatherReport.NowSky;
            NowTemp.Text = weatherReport.NowTemp.ToString() + "°";
            High.Text = "H: " + weatherReport.High + "°";
            Low.Text = "L: " + weatherReport.Low + "°";

            if (Properties.Settings.Default.ShowIconOnTaskbar)
                Widget.Parent.ShowInTaskbar = true;

            Widget.ResourceManager = new ResourceManager(E.Path + "\\WeatherClock", null);
            Icon.Source = new BitmapImage(new Uri(Widget.ResourceManager.GetResourcePath(string.Format("Weather\\weather_{0}.png", weatherReport.NowSkyCode))));

            if (Properties.Settings.Default.ShowIconOnTaskbar)
            {
                if (!string.IsNullOrEmpty(weatherReport.NowSky))
                    Widget.Parent.Title = weatherReport.NowSky;
                Widget.Parent.Icon = Icon.Source;
            }

            if (Properties.Settings.Default.ShowIconOnTaskbar && Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager.IsPlatformSupported)
            {
                System.Drawing.Icon oicon = DrawIcon(weatherReport.NowTemp); //System.Drawing.Icon.FromHandle(bitmap.GetHicon());
                Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager.Instance.SetOverlayIcon(Widget.Parent, oicon, "test");
            }

            for (int i = 0; i < ForecastPanel.Children.Count; i++)
            {
                var item = (ForecastItem)ForecastPanel.Children[i];
                item.Initialize();
                item.Day.Text = DateTime.Today.AddDays(i + 1).ToString("ddd");
                if (weatherReport.Forecast != null && weatherReport.Forecast.Count == 5)
                {
                    item.Icon.Source = new BitmapImage(new Uri(Widget.ResourceManager.GetResourcePath(string.Format("Weather\\weather_{0}.png", weatherReport.Forecast[i].SkyCode))));
                    item.TemperatureH.Text = weatherReport.Forecast[i].HighTemperature.ToString() + "°";
                    item.TemperatureL.Text = " " + weatherReport.Forecast[i].LowTemperature.ToString() + "°";
                    item.Url = weatherReport.Forecast[i].Url;
                }
            }

            //FItem1.Day.Text = Widget.LocaleManager.GetString("Today");
            FItem2.Day.Text = Widget.LocaleManager.GetString("Tomorrow");


            //ForecastGrid.Visibility = Properties.Settings.Default.ShowForecast ? Visibility.Visible : Visibility.Collapsed;

            GetWeatherProviders();

            var optionsItem = new MenuItem();
            optionsItem.Header = Widget.LocaleManager.GetString("Options");
            optionsItem.Click += optionsItem_Click;

            var refreshItem = new MenuItem();
            refreshItem.Header = Widget.LocaleManager.GetString("Refresh");
            refreshItem.Click += new RoutedEventHandler(RefreshItemClick);

            lastCitiesItem = new MenuItem();
            lastCitiesItem.Header = Widget.LocaleManager.GetString("LastResults");
            lastCitiesItem.IsEnabled = false;
            Widget.Parent.ContextMenu.Opened += new RoutedEventHandler(ContextMenuOpened);

            Widget.Parent.ContextMenu.Items.Insert(0, new Separator());
            Widget.Parent.ContextMenu.Items.Insert(0, optionsItem);
            Widget.Parent.ContextMenu.Items.Insert(0, lastCitiesItem);
            Widget.Parent.ContextMenu.Items.Insert(0, refreshItem);

            if (Properties.Settings.Default.TimeMode == 1)
                hoursFormat = "hh";

            Scale.ScaleX = Properties.Settings.Default.ScaleFactor;

            options = new Options(this);

            timer.Start();
            weatherTimer.Start();

            if (string.IsNullOrEmpty(Properties.Settings.Default.UserPic))
            {
                string userpic = Path.GetTempPath() + "\\" + Environment.UserName + ".bmp";
                if (File.Exists(userpic))
                {
                    Properties.Settings.Default.UserPic = userpic;
                    UserPic.Source = new BitmapImage(new Uri(userpic));
                }
            }
            else
                UserPic.Source = new BitmapImage(new Uri(Properties.Settings.Default.UserPic));

            if (Properties.Settings.Default.ShowPictures)
            {
                string picsPath = Properties.Settings.Default.PicturesFolder;
                if (string.IsNullOrEmpty(picsPath))
                    picsPath = E.Root + "\\Pictures";
                if (Directory.Exists(picsPath))
                {
                    var pics = from x in Directory.GetFiles(picsPath, "*.*", SearchOption.AllDirectories)
                               where x.ToLower().EndsWith("jpg") || x.ToLower().EndsWith("png")
                               select x;
                    foreach (var p in pics)
                    {
                        pictures.Add(p);
                    }
                    if (pictures.Count > 0)
                        Picture.Source = new BitmapImage(new Uri(pictures[r.Next(0, pictures.Count)]));
                }
            }
            else
            {
                PicturesGrid.Visibility = Visibility.Collapsed;
            }
        }

        void ContextMenuOpened(object sender, RoutedEventArgs e)
        {
            lastCitiesItem.Items.Clear();
            if (Properties.Settings.Default.LastCities != null && Properties.Settings.Default.LastCities.Count > 0)
            {
                lastCitiesItem.IsEnabled = true;
                lastCitiesItem.Header = Widget.LocaleManager.GetString("LastResults");
                foreach (string city in Properties.Settings.Default.LastCities)
                {
                    var subItem = new MenuItem();
                    string c = city.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries)[0];
                    subItem.Header = c;
                    subItem.Click += new RoutedEventHandler(subItem_Click);
                    lastCitiesItem.Items.Add(subItem);
                }
            }
            else
                lastCitiesItem.IsEnabled = false;
        }

        void RefreshItemClick(object sender, RoutedEventArgs e)
        {
            weatherTimer_Tick(null, EventArgs.Empty);
        }

        void subItem_Click(object sender, RoutedEventArgs e)
        {
            int index = lastCitiesItem.Items.IndexOf(sender);
            if (index > -1)
            {
                string c = Properties.Settings.Default.LastCities[index].Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries)[1];
                Properties.Settings.Default.LocationCode = c;
                RefreshItemClick(sender, e);
                //MessageBox.Show(Widget.Sett.LastCities[index].City);
            }
        }

        private System.Drawing.Icon MakeIcon(int degrees, int skycode)
        {
            System.Drawing.Icon oIcon = null;
            try
            {
                System.Drawing.Bitmap bm = new System.Drawing.Bitmap(Widget.ResourceManager.GetResourcePath(string.Format("Weather\\weather_{0}.png", skycode)));
                System.Drawing.Graphics g = System.Drawing.Graphics.FromImage((System.Drawing.Image)bm);
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                System.Drawing.Font oFont = new System.Drawing.Font("Segoe UI", 12, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
                if (degrees < 10 && degrees > -10)
                {
                    g.DrawString(degrees.ToString(), oFont, new System.Drawing.SolidBrush(System.Drawing.Color.Black), 3, 2);
                }
                else
                {
                    g.DrawString(degrees.ToString(), oFont, new System.Drawing.SolidBrush(System.Drawing.Color.Black), 1, 2);
                }
                oIcon = System.Drawing.Icon.FromHandle(bm.GetHicon());
                oFont.Dispose();
                g.Dispose();
                bm.Dispose();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.InnerException.ToString());
            }

            return oIcon;

        }

        private System.Drawing.Icon DrawIcon(int degrees)
        {

            System.Drawing.Icon oIcon = null;
            try
            {
                System.Drawing.Bitmap bm = new System.Drawing.Bitmap(Widget.ResourceManager.GetResourcePath("Weather\\overlay_icon.png"));
                System.Drawing.Graphics g = System.Drawing.Graphics.FromImage((System.Drawing.Image)bm);
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                System.Drawing.Font oFont = new System.Drawing.Font("Arial", 18, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Pixel);
                switch (degrees.ToString().Length)
                {
                    case (1):
                        g.DrawString(degrees.ToString(), oFont, new System.Drawing.SolidBrush(System.Drawing.Color.Black), 8, 0);
                        break;
                    case (2):
                        g.DrawString(degrees.ToString(), oFont, new System.Drawing.SolidBrush(System.Drawing.Color.Black), 3, 0);
                        break;
                    case (3):
                        g.DrawString(degrees.ToString(), oFont, new System.Drawing.SolidBrush(System.Drawing.Color.Black), -2, 0);
                        break;
                }
                /*if (degrees < 10 && degrees > -10)
                {
                    g.DrawString(degrees.ToString(), oFont, new System.Drawing.SolidBrush(System.Drawing.Color.Black), 0, 0);
                }
                else
                {
                    g.DrawString(degrees.ToString(), oFont, new System.Drawing.SolidBrush(System.Drawing.Color.Black), 3, 0);
                }*/
                oIcon = System.Drawing.Icon.FromHandle(bm.GetHicon());
                oFont.Dispose();
                g.Dispose();
                bm.Dispose();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }

            return oIcon;

        }

        private void GetWeatherProviders()
        {
            if (Directory.Exists(E.ExtensionsPath + "\\Weather"))
            {
                providers = new List<WeatherProvider>();
                var files = from x in Directory.GetFiles(E.ExtensionsPath + "\\Weather")
                            where x.EndsWith(".dll")
                            select x;
                foreach (var f in files)
                {
                    var p = new WeatherProvider(f);
                    providers.Add(p);
                    if (Properties.Settings.Default.WeatherProvider == p.Name)
                    {
                        currentProvider = p;
                        p.Load();
                    }
                }
            }
        }

        public void UpdateSettings()
        {
            Scale.ScaleX = Properties.Settings.Default.ScaleFactor;
            Scale.ScaleY = Scale.ScaleX;

            if (E.Locale != Widget.LocaleManager.LocaleCode)
                Widget.LocaleManager.LoadLocale(E.Locale);

            if (Properties.Settings.Default.ShowPictures)
                PicturesGrid.Visibility = System.Windows.Visibility.Visible;
            else
                PicturesGrid.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (DateTime.Now.ToString(hoursFormat) != Hours.Text)
            {
                Hours.Text = DateTime.Now.ToString(hoursFormat);
                var s = Hours.Resources["UpdateAnim"] as Storyboard;
                s.Begin(Hours);
            }

            if (DateTime.Now.ToString("mm") != Minutes.Text)
            {
                Minutes.Text = DateTime.Now.ToString("mm");
                var s = Minutes.Resources["UpdateAnim"] as Storyboard;
                s.Begin(Minutes);
            }

            if (lastHour != DateTime.Now.Hour)
            {
                lastHour = DateTime.Now.Hour;
                for (int i = 0; i < ForecastPanel.Children.Count; i++)
                {
                    ForecastItem item = (ForecastItem)ForecastPanel.Children[i];
                    item.Initialize();
                    item.Day.Text = DateTime.Today.AddDays(i + 1).ToString("ddd").ToLower();
                    if (weatherReport.Forecast != null && weatherReport.Forecast.Count == 5)
                    {
                        item.Icon.Source = new BitmapImage(new Uri(Widget.ResourceManager.GetResourcePath(string.Format("Weather\\weather_{0}.png", weatherReport.Forecast[i].SkyCode))));
                        item.TemperatureH.Text = weatherReport.Forecast[i].HighTemperature.ToString() + "°";
                        item.TemperatureL.Text = weatherReport.Forecast[i].LowTemperature.ToString() + "°";
                        item.Url = weatherReport.Forecast[i].Url;
                    }
                }

                //FItem1.Day.Text = Widget.LocaleManager.GetString("Today");
                FItem2.Day.Text = Widget.LocaleManager.GetString("Tomorrow");

                Month.Text = DateTime.Today.ToString("MMMM");
                Day.Text = DateTime.Today.Day.ToString();
            }

            count++;

            if (count >= Properties.Settings.Default.PicsInterval * 60 && Properties.Settings.Default.ShowPictures)
            {
                count = 0;

                if (pictures.Count > 0)
                    PictureBg.Source = new BitmapImage(new Uri(pictures[r.Next(0, pictures.Count)]));

                Storyboard s = Resources["SwitchPictureAnim"] as Storyboard;
                s.Begin(Picture);
            }
        }

        public void weatherTimer_Tick(object sender, EventArgs e)
        {
            ThreadStart threadStarter = RefreshWeather;
            var thread = new Thread(threadStarter);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        public void RefreshWeather()
        {
            try
            {
                GetWeatherReport();

                if (weatherReport != null)
                    WeatherGrid.Dispatcher.Invoke((Action)UpdateWeatherData, null);
                ForecastPanel.Dispatcher.Invoke((Action)UpdateForecastData, null);
            }
            catch (Exception ex)
            {
                //WeatherPanel.Dispatcher.Invoke((Action)RefreshWeatherFail, null);
                HTCHome.Core.Logger.Log(ex.ToString());
            }
        }

        private void GetWeatherReport()
        {
            WeatherReport temp;
            if (Properties.Settings.Default.LocationCode != string.Empty)
            {
                temp = currentProvider.GetWeatherReport(E.Locale, Properties.Settings.Default.LocationCode, Properties.Settings.Default.DegreeType);
            }
            else
            {
                temp = currentProvider.GetWeatherReport(E.Locale, string.Empty, Properties.Settings.Default.DegreeType);
            }

            if (temp != null)
                weatherReport = temp;

        }

        private void UpdateWeatherData()
        {
            if (!string.IsNullOrEmpty(weatherReport.Location))
            {
                if (weatherReport.Location.Contains(","))
                    weatherReport.Location = weatherReport.Location.Substring(0, weatherReport.Location.IndexOf(","));

                Location.Text = weatherReport.Location;

                FlipWeatherIcon();

                if (Properties.Settings.Default.ShowIconOnTaskbar && Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager.IsPlatformSupported)
                {
                    System.Drawing.Icon oicon = DrawIcon(weatherReport.NowTemp);
                    Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager.Instance.SetOverlayIcon(Widget.Parent, oicon, "");
                }
            }

            NowTemp.Text = weatherReport.NowTemp + "°";
            High.Text = "H: " + weatherReport.High + "°";
            Low.Text = "L: " + weatherReport.Low + "°";

            if (!string.IsNullOrEmpty(weatherReport.NowSky))
                Weather.Text = weatherReport.NowSky;
        }

        private void UpdateForecastData()
        {
            for (int i = 0; i < ForecastPanel.Children.Count; i++)
            {
                var item = (ForecastItem)ForecastPanel.Children[i];
                if (weatherReport.Forecast != null && weatherReport.Forecast.Count == 5)
                {
                    item.FlipWeather(weatherReport.Forecast[i].SkyCode);
                    item.TemperatureH.Text = weatherReport.Forecast[i].HighTemperature.ToString() + "°";
                    item.TemperatureL.Text = " " + weatherReport.Forecast[i].LowTemperature.ToString() + "°";
                    item.Url = weatherReport.Forecast[i].Url;
                    item.ToolTip = weatherReport.Forecast[i].Text;
                }
            }
        }

        private void RefreshWeatherFail()
        {
            //MessageBox.Show("Fail");
        }

        private void FlipWeatherIcon()
        {
            Icon.Source = new BitmapImage(new Uri(Widget.ResourceManager.GetResourcePath(string.Format("Weather\\weather_{0}.png", weatherReport.NowSkyCode))));
            if (Properties.Settings.Default.ShowIconOnTaskbar)
            {
                if (!string.IsNullOrEmpty(weatherReport.NowSky))
                    Widget.Parent.Title = weatherReport.NowSky;
            }
        }

        public void icon_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount > 1 && !string.IsNullOrEmpty(weatherReport.Url))
                WinAPI.ShellExecute(IntPtr.Zero, "open", weatherReport.Url, "", "", 0);
        }

        void optionsItem_Click(object sender, RoutedEventArgs e)
        {
            ShowOptions();
        }

        public void ShowOptions()
        {
            if (options.IsVisible)
            {
                options.Activate();
                return;
            }
            options = new Options(this);

            if (E.Locale == "he-IL" || E.Locale == "ar-SA")
            {
                options.FlowDirection = FlowDirection.RightToLeft;
            }
            else
            {
                options.FlowDirection = FlowDirection.LeftToRight;
            }

            options.ShowDialog();
        }

        public void Unload()
        {
            if (weatherReport != null)
            {
                weatherReport.Write(E.Path + "\\WeatherClock\\Weather.data");
            }
        }

        private void DoubleAnimation_Completed(object sender, EventArgs e)
        {
            Picture.Source = PictureBg.Source;
            PictureBg.Source = null;
        }

        private void UserGrid_Drop(object sender, DragEventArgs e)
        {
            var files = from x in ((string[])e.Data.GetData(DataFormats.FileDrop, true))
                        where x.ToLower().EndsWith(".png") || x.ToLower().EndsWith(".jpg")
                        select x;
            if (files != null && files.Count() > 0)
            {
                Properties.Settings.Default.UserPic = files.First();
                UserPic.Source = new BitmapImage(new Uri(Properties.Settings.Default.UserPic));
            }
        }
    }
}
